package org.myapp.event;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.espertech.esper.client.EventBean;
import com.espertech.esper.client.UpdateListener;

public class MyListener implements UpdateListener {

	private final EventType eventType;
	private String previousItemName;
	private double previousRate;
	private boolean isValid;
	private Map<String, Integer> product = new HashMap<>();

	public Map<String, Integer> getProduct() {
		return product;
	}

	public void setProduct(Map<String, Integer> product) {
		this.product = product;
	}

	public boolean isValid() {
		return isValid;
	}

	public void setValid(boolean isValid) {
		this.isValid = isValid;
	}

	private static final Logger LOGGER = LoggerFactory
			.getLogger(MyListener.class);

	public MyListener(final EventType eventType, Map<String, Integer> product) {
		this.eventType = eventType;
		this.previousItemName = "";
		this.previousRate = 0;
		this.product = product;
	}
	
	public void update(EventBean[] newEvents, EventBean[] oldEvents) {

		try {
			EventBean event = newEvents[0];
			
			switch (this.eventType) {
			case AVG_PRICE:
				LOGGER.warn("avg = " + event.get("avg(price)"));
				break;
			case MORE_1000:
				LOGGER.warn("price (> 1000) = " + event.get("itemName") + " => " + event.get("price") + " €");
				break;
			case SAME_ITEM:
				String newItemName = event.get("itemName").toString();
				if (newItemName.equals(this.previousItemName)) {
					LOGGER.warn("Same item = " + event.get("itemName"));
				}
				this.previousItemName = newItemName;
				break;
			case RATE_CMD:
				if(event.get("num_commande") != null) {
					Double currentRate = Double.parseDouble(event.get("num_commande").toString());
					
					if(currentRate > this.previousRate * 1.1) {
						LOGGER.warn("Rate (>10%) = " + event.get("num_commande"));
					}

					this.previousRate = currentRate;
				}
				break;
			case CMD_INVALID:
				
				// produits invalides : 
				// si prix <= 0 (pas de gratuité dans notre magasin)
				// si le stock est = 0
				// si le produit n'existe pas
				
				String item = event.get("itemName").toString();
				double price = Double.parseDouble(event.get("price").toString());
				boolean productExist = false;
				
				this.setValid(false);
				
				if(price <= 0) {
					LOGGER.warn("Le prix du produit (" + price + " €) est invalide ! ");
				} else {
					for(Entry<String,Integer> catalog : this.product.entrySet()){
						if(item.equals(catalog.getKey())) 
						{
							productExist = true;
							if(catalog.getValue() == 0) {
								LOGGER.warn("Le produit demandé (" + item + ") n'est plus en stock !");
							} else {
								catalog.setValue(catalog.getValue() - 1);
								this.setValid(true);
							}
							break;
						}
					}
					if(!productExist) LOGGER.warn("Le produit (" + item + ") n'existe pas dans notre magasin !");
				}
				
				break;
			default:
				break;
			}
		} catch (Throwable t) {
			LOGGER.warn(t.toString());
		}
	}

	public enum EventType {
		AVG_PRICE,
		MORE_1000,
		RATE_CMD,	
		CMD_INVALID,
		SAME_ITEM;
	}
}
